package linker

import (
	"bytes"
	"debug/elf"
	"rvld/src/utils"
	"strconv"
	"strings"
)

func (s *Sym) IsAbs() bool {
	return s.Shndx == uint16(elf.SHN_ABS)
}

func (s *Sym) IsCommon() bool {
	return s.Shndx == uint16(elf.SHN_COMMON)
}

func (s *Sym) IsUndef() bool {
	return s.Shndx == uint16(elf.SHN_UNDEF)
}

func (a *ArHdr) GetSize() int {
	size, err := strconv.Atoi(strings.TrimSpace(string(a.Size[:])))
	utils.ThisMustNo(err)
	return size
}

func (a *ArHdr) IsStrtab() bool {
	return a.HasPrefix("// ")
}

func (a *ArHdr) HasPrefix(s string) bool {
	return strings.HasPrefix(string(a.Name[:]), s)
}

func (a *ArHdr) IsSymtab() bool {
	return a.HasPrefix("/ ") || a.HasPrefix("/SYM64/ ")
}

func (a *ArHdr) ReadName(strTab []byte) string {
	if a.HasPrefix("/") {
		start, err := strconv.Atoi(strings.TrimSpace(string(a.Name[1:])))
		utils.ThisMustNo(err)
		end := start + bytes.Index(strTab[start:], []byte("/\n"))
		return string(strTab[start:end])
	}

	end := bytes.Index(a.Name[:], []byte("/"))
	utils.ThisAssert(end != -1)
	return string(a.Name[:end])
}

func ElfGetName(strTab []byte, offset uint32) string {
	length := uint32(bytes.Index(strTab[offset:], []byte{0}))
	return string(strTab[offset : offset+length])
}

// DONE
